/**
 * 
 */
package com.ctn.task.manage;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.annotation.PostConstruct;

import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import com.ctn.task.TaskConstant;
import com.ctn.task.entity.Task;

/**
 * @author Zale
 * 
 */
@Component
public class TaskManage {
	private static ExecutorService VERY_HIGH_QUEUE = Executors
			.newFixedThreadPool(TaskConstant.VERY_HIGH_MAX_THREADS);
	private static ExecutorService HIGH_QUEUE = Executors
			.newFixedThreadPool(TaskConstant.HIGH_MAX_THREADS);
	private static ExecutorService NORMAL_QUEUE = Executors
			.newFixedThreadPool(TaskConstant.NORMAL_MAX_THREADS);
	private static ExecutorService LOW_QUEUE = Executors
			.newFixedThreadPool(TaskConstant.LOW_MAX_THREADS);
	private static ExecutorService VERY_LOW_QUEUE = Executors
			.newFixedThreadPool(TaskConstant.VERY_LOW_MAX_THREADS);

	private List<Task> waitingTasks;
	private List<Task> didTasks;

	public List<Task> getWaitingTasks() {
		return waitingTasks;
	}

	public void setWaitingTasks(List<Task> waitingTasks) {
		this.waitingTasks = waitingTasks;
	}

	public List<Task> getDidTasks() {
		return didTasks;
	}

	public void setDidTasks(List<Task> didTasks) {
		this.didTasks = didTasks;
	}

	public void addNewTask(Task task) {
		if (!waitingTasks.contains(task)) {
			waitingTasks.add(task);
		}
	}
	@PostConstruct
	private void initDefaults() {
		
		if (waitingTasks == null) {
			waitingTasks = new ArrayList<Task>();
		}
		if(didTasks == null){
			didTasks = new ArrayList<Task>();
		}
		
	}
	public void updateTask(Task task){
		synchronized (waitingTasks) {
			waitingTasks.remove(task);
			waitingTasks.add(task);
		}
	}
	@Scheduled(fixedDelay=10000)
	public void process() {
		synchronized (waitingTasks) {
			for (final Task task : waitingTasks) {
				switch (task.getPriority()) {
				case very_high:
					TaskManage.VERY_HIGH_QUEUE.execute(new DoTask(task));
					break;
				case high:
					TaskManage.HIGH_QUEUE.execute(new DoTask(task));
					break;
				case normal:
					TaskManage.NORMAL_QUEUE.execute(new DoTask(task));
					break;
				case low:
					TaskManage.LOW_QUEUE.execute(new DoTask(task));
					break;
				case very_low:
					TaskManage.VERY_LOW_QUEUE.execute(new DoTask(task));
					break;
				default:
					break;
				}
			}
		}
	}
	
	class DoTask implements Runnable{
		private Task task;
		
		/**
		 * @param task
		 */
		public DoTask(Task task) {
			super();
			this.task = task;
		}

		@Override
		public void run() {
			task.getExecutor().execute(task.getResult());
			didTasks.add(task);			
		}
		
	}
}
